home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
pc
/
files
/
t_unix
/
bs941029.tgz
/
bbsx-941029.tar
/
bbsx
/
bbs_ufunc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-29
|
56KB
|
2,282 lines
#define _HPUX_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <sys/time.h>
#include <fcntl.h>
#include <pwd.h>
#include <termio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ndbm.h>
#include <fnmatch.h>
#include "bbs.h"
#include "buildsaddr.h"
#include "strdup.h"
#include "callvalid.h"
#include "lockfile.h"
/*---------------------------------------------------------------------------*/
void errorstop(int line)
{
char buf[80];
sprintf(buf, "Fatal error in line %d", line);
perror(buf);
fprintf(stderr, "Program stopped.\n");
free(alias_table);
exit(1);
}
/*---------------------------------------------------------------------------*/
/* Use private function because some platforms are broken, eg 386BSD */
int Xtolower(int c)
{
return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
}
/*---------------------------------------------------------------------------*/
/* Use private function because some platforms are broken, eg 386BSD */
int Xtoupper(int c)
{
return (c >= 'a' && c <= 'z') ? (c - 'a' + 'A') : c;
}
/*---------------------------------------------------------------------------*/
char *strupc(char *s)
{
char *p;
for (p = s; *p = Xtoupper(*p); p++) ;
return s;
}
/*---------------------------------------------------------------------------*/
char *strlwc(char *s)
{
char *p;
for (p = s; *p = Xtolower(*p); p++) ;
return s;
}
/*---------------------------------------------------------------------------*/
int Strcasecmp(const char *s1, const char *s2)
{
while (Xtolower(*s1) == Xtolower(*s2)) {
if (!*s1) return 0;
s1++;
s2++;
}
return Xtolower(*s1) - Xtolower(*s2);
}
/*---------------------------------------------------------------------------*/
int Strncasecmp(const char *s1, const char *s2, int n)
{
while (--n >= 0 && Xtolower(*s1) == Xtolower(*s2)) {
if (!*s1) return 0;
s1++;
s2++;
}
return n < 0 ? 0 : Xtolower(*s1) - Xtolower(*s2);
}
/*---------------------------------------------------------------------------*/
char *strtrim(char *s)
{
char *p;
for (p = s; *p; p++) ;
while (--p >= s && isspace(*p & 0xff)) ;
p[1] = 0;
return s;
}
/*---------------------------------------------------------------------------*/
const char *strcasepos(const char *str, const char *pat)
{
const char *s, *p;
for (; ; str++)
for (s = str, p = pat; ; s++, p++) {
if (!*p) return str;
if (!*s) return 0;
if (Xtolower(*s) != Xtolower(*p)) break;
}
}
/*---------------------------------------------------------------------------*/
char *getstring(char *s)
{
char *p;
static int chr, lastchr;
fflush(stdout);
alarm(1 * HOURS);
for (p = s; ; ) {
*p = 0;
lastchr = chr;
chr = getchar();
if (stopped) {
alarm(0);
clearerr(stdin);
*s = 0;
return s;
}
if (ferror(stdin) || feof(stdin)) {
alarm(0);
return 0;
}
switch (chr) {
case EOF:
alarm(0);
return (p == s) ? 0 : s;
case 0:
break;
case '\r':
alarm(0);
return s;
case '\n':
if (lastchr != '\r') {
alarm(0);
return s;
}
break;
default:
*p++ = chr;
}
}
}
/*---------------------------------------------------------------------------*/
char *timestr(long gmt)
{
static char buf[20];
struct tm *tm;
tm = gmtime(&gmt);
sprintf(buf, "%02d%.3s%02d/%02d%02d",
tm->tm_mday,
monthnames + 3 * tm->tm_mon,
tm->tm_year % 100,
tm->tm_hour,
tm->tm_min);
return buf;
}
/*---------------------------------------------------------------------------*/
char *rfc822_date(long gmt)
{
static char buf[32];
struct tm *tm;
tm = gmtime(&gmt);
sprintf(buf, "%.3s, %d %.3s %02d %02d:%02d:%02d GMT",
daynames + 3 * tm->tm_wday,
tm->tm_mday,
monthnames + 3 * tm->tm_mon,
tm->tm_year % 100,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
return buf;
}
/*---------------------------------------------------------------------------*/
long parse_date(const char *str)
{
char *p;
char monthstr[4];
long t;
struct tm tm;
if (sscanf((char *) str,
"%*s %d %3s %d %d:%d:%d",
&tm.tm_mday,
monthstr,
&tm.tm_year,
&tm.tm_hour,
&tm.tm_min,
&tm.tm_sec) != 6) return -1;
if (strlen(monthstr) != 3) return -1;
p = strstr(monthnames, monthstr);
if (!p) return -1;
tm.tm_mon = (p - monthnames) / 3;
tm.tm_isdst = 0;
#if defined __hpux || defined linux
t = mktime(&tm);
if (t != -1) return t - timezone;
#elif defined sun
return timegm(&tm);
#endif
return -1;
}
/*---------------------------------------------------------------------------*/
void make_parent_directories(const char *filename)
{
char *p, dirname[1024];
strcpy(dirname, filename);
p = strrchr(dirname, '/');
if (!p) halt();
*p = 0;
if (!mkdir(dirname, 0755)) return;
if (errno != ENOENT) halt();
make_parent_directories(dirname);
if (mkdir(dirname, 0755)) halt();
}
/*---------------------------------------------------------------------------*/
char *getfilename(int mesg)
{
static char buf[12];
char cname[18];
char comm[50];
FILE *fp;
sprintf(buf,
"%02x/%02x/%02x/%02x",
(mesg >> 24) & 0xff,
(mesg >> 16) & 0xff,
(mesg >> 8) & 0xff,
(mesg ) & 0xff);
strcpy(cname,buf);
strcat(cname,compressext);
if (fp=fopen(cname,"r"))
{
fclose(fp);
strcpy(comm,compress);
strcat(comm," ");strcat(comm,uncompressoption);strcat(comm," ");
strcat(comm,cname);
system(comm);
}
return buf;
}
/*---------------------------------------------------------------------------*/
void get_seq(void)
{
char buf[16];
char fname[1024];
struct flock flk;
if (mode != BBS || is_tell_user) return;
sprintf(fname, "%s/%s", user.dir, SEQFILE);
#ifdef __hpux
setresgid(user.gid, user.gid, 0);
setresuid(user.uid, user.uid, 0);
fdseq = open(fname, O_RDWR | O_CREAT, 0644);
setresuid(0, 0, 0);
setresgid(0, 0, 0);
#else
setregid(0, user.gid);
setreuid(0, user.uid);
fdseq = open(fname, O_RDWR | O_CREAT, 0644);
setreuid(0, 0);
setregid(0, 0);
#endif
if (fdseq < 0) halt();
flk.l_type = F_WRLCK;
flk.l_whence = SEEK_SET;
flk.l_start = 0;
flk.l_len = 0;
if (fcntl(fdseq, F_SETLK, &flk) == -1) {
if (level != MBOX)
puts("Sorry, you are already running another BBS.\n");
exit(1);
}
if (read(fdseq, buf, sizeof(buf)) >= 2) user.seq = atoi(buf);
}
/*---------------------------------------------------------------------------*/
void put_seq(void)
{
char buf[16];
int n;
if (mode != BBS || is_tell_user) return;
sprintf(buf, "%d\n", user.seq);
n = strlen(buf);
if (lseek(fdseq, 0L, SEEK_SET)) halt();
if (write(fdseq, buf, n) != n) halt();
}
/*---------------------------------------------------------------------------*/
void wait_for_prompt(void)
{
char buf[1024];
int l;
FILE *dbfp;
do {
if (!getstring(buf)) exit(1);
l = strlen(buf);
if (*buf == '[') {
parse_command_line(buf);
}
} while (!l || buf[l-1] != '>');
}
/*---------------------------------------------------------------------------*/
int get_index(int n, struct index *index)
{
int i1, i2, im;
long pos;
i1 = 0;
if (lseek(fdindex, 0L, SEEK_SET)) halt();
if (read(fdindex, index, sizeof(struct index)) != sizeof(struct index)) return 0;
if (n == index->mesg) return 1;
if (n < index->mesg) return 0;
if ((pos = lseek(fdindex, -sizeof(struct index), SEEK_END)) < 0) halt();
i2 = (int) (pos / sizeof(struct index));
if (read(fdindex, index, sizeof(struct index)) != sizeof(struct index)) halt();
if (n == index->mesg) return 1;
if (n > index->mesg) return 0;
while (i1 + 1 < i2) {
im = (i1 + i2) / 2;
if (lseek(fdindex, im * sizeof(struct index), SEEK_SET) < 0) halt();
if (read(fdindex, index, sizeof(struct index)) != sizeof(struct index)) halt();
if (n == index->mesg) return 1;
if (n > index->mesg)
i1 = im;
else
i2 = im;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int read_allowed(const struct index *index)
{
if (index->flags & DELETED) return 0;
if (level == ROOT) return 1;
if (index->to[1]) return 1;
return 0;
}
/*---------------------------------------------------------------------------*/
char *get_user_from_path(char *path)
{
char *cp;
cp = strrchr(path, '!');
return cp ? (cp + 1) : path;
}
/*---------------------------------------------------------------------------*/
char *get_host_from_path(char *path)
{
char *cp;
static char tmp[1024];
strcpy(tmp, path);
cp = strrchr(tmp, '!');
if (!cp) return myhostname;
*cp = 0;
cp = strrchr(tmp, '!');
return cp ? (cp + 1) : tmp;
}
/*---------------------------------------------------------------------------*/
int msg_uniq(const char *bid, const char *mid)
{
DBM * bid_db;
datum datum_bid;
datum datum_offset;
long offset;
struct index index;
datum_bid.dptr = (char *) bid;
datum_bid.dsize = strlen(bid);
if (!(bid_db = dbm_open(BID_DB, O_RDWR | O_CREAT, 0644))) halt();
datum_offset = dbm_fetch(bid_db, datum_bid);
dbm_close(bid_db);
if (!datum_offset.dptr) return 1;
memcpy((char *) &offset, datum_offset.dptr, sizeof(offset));
if (lseek(fdindex, offset, SEEK_SET) != offset) halt();
if (read(fdindex, &index, sizeof(struct index )) != sizeof(struct index )) halt();
if (strcmp(index.bid, bid)) halt();
return index.date < time((long *) 0) - 90 * DAYS;
}
/*---------------------------------------------------------------------------*/
void send_to_bbs(struct mail *mail)
{
DBM * bid_db;
FILE *fp;
datum datum_bid;
datum datum_offset;
struct index index;
struct strlist *p;
long offset;
if (!*mail->subject) return;
if ((fdlock = lock_file(LOCKFILE, 0)) < 0) halt();
if (msg_uniq(mail->bid, mail->mid)) {
if (lseek(fdindex, -sizeof(struct index), SEEK_END) < 0)
index.mesg = 1;
else {
if (read(fdindex, &index, sizeof(struct index)) != sizeof(struct index)) halt();
index.mesg++;
}
index.date = mail->date;
index.lifetime_h = (mail->lifetime + 1) >> 8;
index.lifetime_l = (mail->lifetime + 1);
strcpy(index.bid, mail->bid);
strupc(index.bid);
strncpy(index.subject, mail->subject, LEN_SUBJECT);
index.subject[LEN_SUBJECT] = 0;
strncpy(index.to, get_user_from_path(mail->to), LEN_TO);
index.to[LEN_TO] = 0;
strupc(index.to);
strncpy(index.orig_to, get_user_from_path(mail->orig_to), LEN_TO);
index.orig_to[LEN_TO] = 0;
strupc(index.orig_to);
strncpy(index.at, get_host_from_path(mail->to), LEN_AT);
index.at[LEN_AT] = 0;
strupc(index.at);
strncpy(index.from, get_user_from_path(mail->from), LEN_FROM);
index.from[LEN_FROM] = 0;
strupc(index.from);
index.flags = 0;
index.size = 0;
#ifdef BOXBIN
if (mail->bin) {
index.flags |= BINARY;
}
#endif
if (!(fp = fopen(getfilename(index.mesg), "w"))) {
make_parent_directories(getfilename(index.mesg));
if (!(fp = fopen(getfilename(index.mesg), "w"))) halt();
}
if (strcmp(index.to, "E") && strcmp(index.to, "M"))
for (p = mail->head; p; p = p->next) {
if (fputs(p->str, fp) == EOF) halt();
if (putc('\n', fp) == EOF) halt();
index.size += (strlen(p->str) + 1);
}
fclose(fp);
offset = lseek(fdindex, 0L, SEEK_END);
if (offset < 0) halt();
if (!(bid_db = dbm_open(BID_DB, O_RDWR | O_CREAT, 0644))) halt();
datum_bid.dptr = index.bid;
datum_bid.dsize = strlen(index.bid);
datum_offset.dptr = (char *) &offset;
datum_offset.dsize = sizeof(offset);
if (dbm_store(bid_db, datum_bid, datum_offset, DBM_REPLACE) < 0) halt();
dbm_close(bid_db);
if (write(fdindex, &index, sizeof(struct index)) != sizeof(struct index)) halt();
if (index.mesg == user.seq + 1) {
user.seq = index.mesg;
if (level != MBOX)
put_seq();
}
}
close(fdlock);
}
/*---------------------------------------------------------------------------*/
void send_to_mail(struct mail *mail)
{
FILE *fp;
char command[1024];
int i;
struct strlist *p;
switch (fork()) {
case -1:
halt();
case 0:
setgid(0);
setuid(0);
for (i = open_max() - 1; i >= 0; i--) close(i);
setsid();
fopen("/dev/null", "r+");
fopen("/dev/null", "r+");
fopen("/dev/null", "r+");
switch (fork()) {
case -1:
_exit(1);
case 0:
#ifdef __386BSD__
sprintf(command, "/usr/sbin/sendmail -oi -oem -f %s %s", mail->from, mail->to);
#else
sprintf(command, "/usr/lib/sendmail -oi -oem -f %s %s", mail->from, mail->to);
#endif
if (!(fp = popen(command, "w"))) _exit(1);
fprintf(fp, "From: %s\n", mail->from);
fprintf(fp, "To: %s\n", mail->to);
fprintf(fp, "Date: %s\n", rfc822_date(mail->date));
if (*mail->subject) fprintf(fp, "Subject: %s\n", mail->subject);
fprintf(fp, "Message-ID: <%s>\n", mail->mid);
if (mail->lifetime != -1)
fprintf(fp, "Expires: %s\n", rfc822_date(mail->date + DAYS * mail->lifetime));
fprintf(fp, "Bulletin-ID: <%s>\n", mail->bid);
putc('\n', fp);
for (p = mail->head; p; p = p->next) {
fputs(p->str, fp);
putc('\n', fp);
}
pclose(fp);
_exit(0);
default:
_exit(0);
}
default:
wait((int *) 0);
}
}
/*---------------------------------------------------------------------------*/
void send_to_news(struct mail *mail)
{
FILE *fp;
char *fromhost;
char *pp;
int fd;
int i;
struct strlist *p;
if (!*mail->subject) return;
if ((fd = open("/usr/bin/rnews", O_RDONLY)) < 0) return;
close(fd);
switch (fork()) {
case -1:
halt();
case 0:
setgid(0);
setuid(0);
for (i = open_max() - 1; i >= 0; i--) close(i);
setsid();
fopen("/dev/null", "r+");
fopen("/dev/null", "r+");
fopen("/dev/null", "r+");
switch (fork()) {
case -1:
_exit(1);
case 0:
if (!(fp = popen("/usr/bin/rnews", "w"))) _exit(1);
fromhost = get_host_from_path(mail->from);
fprintf(fp, "From: %s@%s%s\n", get_user_from_path(mail->from), fromhost, strchr(fromhost, '.') ? "" : ".ampr.org");
fprintf(fp, "Date: %s\n", rfc822_date(mail->date));
fprintf(fp, "Newsgroups: ampr.bbs.%s\n", get_user_from_path(mail->to));
fprintf(fp, "Subject: %s\n", mail->subject);
fprintf(fp, "Message-ID: <%s>\n", mail->mid);
i = strlen(myhostname);
if (!strncmp(mail->from, myhostname, i) && mail->from[i] == '!')
pp = mail->from + i + 1;
else
pp = mail->from;
fprintf(fp, "Path: %s\n", pp);
if (mail->lifetime != -1)
fprintf(fp, "Expires: %s\n", rfc822_date(mail->date + DAYS * mail->lifetime));
fprintf(fp, "Distribution: %s\n", get_host_from_path(mail->to));
fprintf(fp, "Bulletin-ID: <%s>\n", mail->bid);
putc('\n', fp);
p = mail->head;
while (p && p->str[0] == 'R' && p->str[1] == ':')
p = p->next;
while (p &&
(p->str[0] == 'd' && p->str[1] == 'e' && p->str[2] == ' ' ||
p->str[0] == 't' && p->str[1] == 'o' && p->str[2] == ' '))
p = p->next;
while (p && p->str[0] == 0)
p = p->next;
while (p) {
fputs(p->str, fp);
putc('\n', fp);
p = p->next;
}
pclose(fp);
_exit(0);
default:
_exit(0);
}
default:
wait((int *) 0);
}
}
/*---------------------------------------------------------------------------*/
void fix_address(char *addr)
{
char *p1, *p2;
char tmp[1024];
int c, skip;
for (p1 = addr; *p1; p1++)
switch (*p1) {
case '%':
*p1 = '@';
break;
case ',':
*p1 = ':';
break;
case '^':
*p1 = '!';
break;
}
while ((p1 = strchr(addr, '@')) && (p2 = strchr(p1, ':'))) {
*p1 = *p2 = 0;
sprintf(tmp, "%s%s!%s", addr, p1 + 1, p2 + 1);
strcpy(addr, tmp);
}
while (p2 = strrchr(addr, '@')) {
*p2 = 0;
p1 = p2;
while (p1 > addr && *p1 != '!') p1--;
if (p1 == addr)
sprintf(tmp, "%s!%s", p2 + 1, addr);
else {
*p1 = 0;
sprintf(tmp, "%s!%s!%s", addr, p2 + 1, p1 + 1);
}
strcpy(addr, tmp);
}
for (skip = 0, p1 = p2 = addr; c = *p1; p1++) {
if (c == '.' && fix_allowed)
skip = 1;
else if (c == '!')
skip = 0;
if (!skip) *p2++ = c;
}
*p2 = 0;
if (!strchr(addr, '!')) {
sprintf(tmp, "%s!%s", myhostname, addr);
strcpy(addr, tmp);
}
strlwc(addr);
}
/*---------------------------------------------------------------------------*/
struct mail *alloc_mail(void)
{
struct mail *mail;
mail = calloc(1, sizeof(*mail));
mail->lifetime = -1;
return mail;
}
/*---------------------------------------------------------------------------*/
void free_mail(struct mail *mail)
{
struct strlist *p;
while (p = mail->head) {
mail->head = p->next;
free(p);
}
free(mail);
}
/*---------------------------------------------------------------------------*/
void route_mail(struct mail *mail)
{
#define MidSuffix "@bbs.net"
FILE *fp;
char *cp;
char *s;
char *tohost;
char *touser;
int n;
int fdbid;
struct strlist *p;
/* Set date */
mail->date = time((long *) 0);
/* Fix addresses */
fix_address(mail->from);
fix_address(mail->to);
fix_address(mail->orig_to);
/* Check for bogus mails */
strtrim(mail->subject);
if ((cp = get_host_from_header(mail->subject)) && callvalid(cp)) goto Done;
if (level == MBOX && !packetcluster) {
cp = get_user_from_path(mail->to);
if (!cp) goto Done;
if (strlen(cp) > 1) {
if (!mail->head) goto Done;
cp = get_host_from_header(mail->head->str);
if (!cp || !calleq(cp, user.name)) goto Done;
}
}
/* Set bid */
if (!*mail->bid && (cp = strchr(mail->mid, '@')) && !strcmp(cp, MidSuffix)) {
strcpy(mail->bid, mail->mid);
mail->bid[strlen(mail->bid)-strlen(MidSuffix)] = 0;
}
if (!*mail->bid) {
n = 0;
if ((fdbid = lock_file(BIDFILE, 0)) < 0) halt();
if (fp = fopen(BIDFILE, "r")) {
fscanf(fp, "%d", &n);
fclose(fp);
}
n++;
if (!(fp = fopen(BIDFILE, "w")) || fprintf(fp, "%d\n", n) < 0) halt();
fclose(fp);
close(fdbid);
sprintf(mail->bid, "%012d", n);
strncpy(mail->bid, myhostname, strlen(myhostname));
}
mail->bid[LEN_BID] = 0;
strupc(mail->bid);
/* Set mid */
if (!*mail->mid) {
strcpy(mail->mid, mail->bid);
strcat(mail->mid, MidSuffix);
}
/* Remove message delimiters */
for (p = mail->head; p; p = p->next) {
s = p->str;
if (*s == '.' && !s[1]) *s = 0;
while (cp = strchr(s, '\004')) while (cp[0] = cp[1]) cp++;
while (cp = strchr(s, '\032')) while (cp[0] = cp[1]) cp++;
if (!Strncasecmp(s, "***end", 6)) *s = ' ';
}
/* Call delivery agents */
touser = get_user_from_path(mail->to);
tohost = get_host_from_path(mail->to);
if (callvalid(touser) || isvaliduser(touser)) {
send_to_mail(mail);
} else {
if (calleq(tohost, myhostname))
send_to_bbs(mail);
else if (callvalid(tohost))
send_to_mail(mail);
else
send_to_bbs(mail);
if (strcmp(touser, "e") && strcmp(touser, "m")) send_to_news(mail);
}
/* Free mail */
Done:
free_mail(mail);
}
/*---------------------------------------------------------------------------*/
void append_line(struct mail *mail, char *line)
{
struct strlist *p;
p = malloc(sizeof(*p) + strlen(line));
p->next = 0;
strcpy(p->str, line);
if (!mail->head)
mail->head = p;
else
mail->tail->next = p;
mail->tail = p;
}
/*---------------------------------------------------------------------------*/
int get_header_value(const char *name, int do822, char *line, char *value)
{
char *p1, *p2;
int c, comment;
for (; *name; name++, line++)
if (Xtolower(*name) != Xtolower(*line)) return 0;
if (do822) {
for (comment = 0, p1 = line; c = *p1; p1++) {
if (c == '(') comment++;
if (comment) *p1 = ' ';
if (comment && c == ')') comment--;
}
while ((p1 = strchr(line, '<')) && (p2 = strrchr(p1, '>'))) {
*p2 = 0;
line = p1 + 1;
}
}
while (isspace(uchar(*line))) line++;
strcpy(value, strtrim(line));
return 1;
}
/*---------------------------------------------------------------------------*/
char *get_host_from_header(const char *line)
{
char *p, *q;
static char buf[1024];
if (*line == 'R' && line[1] == ':' && (p = strchr(strcpy(buf, line), '@'))) {
p++;
while (*p == ':' || isspace(uchar(*p))) p++;
for (q = p; isalnum(uchar(*q)); q++) ;
*q = 0;
return p;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int host_in_header(char *fname, char *host)
{
FILE *fp;
char buf[1024];
char *p;
if (!(fp = fopen(fname, "r"))) halt();
while (fgets(buf, sizeof(buf), fp))
if ((p = get_host_from_header(buf)) && calleq(p, host)) {
fclose(fp);
return 1;
}
fclose(fp);
return 0;
}
/*---------------------------------------------------------------------------*/
void dir_print(struct dir_entry *p)
{
if (p) {
dir_print(p->left);
if (!stopped)
printf((dir_column++ % 5) < 4 ? "%5d %-8s" : "%5d %s\n", p->count, p->to);
dir_print(p->right);
free(p);
}
}
/*---------------------------------------------------------------------------*/
void bbs(void)
{
FILE *fp;
char line[1024];
char buffer[1024], buf[1024], gen_prompt[1024], *p, *sl;
int k;
long l;
struct tm *tm;
char timestamp[11];
if (level != MBOX) {
printf("BBSX Revision: %s Type ? for help.\n", BBSX_REVISION);
sprintf(line, "%s/%s", user.dir, HUSHFILE);
if (fp = fopen(line, "r")) {
fclose(fp);
} else
get_welcomemsg();
}
if (level != MBOX && (fp = fopen(masterrcfile, "r"))) {
while (fgets(line, sizeof(line), fp)) parse_command_line(line);
fclose(fp);
}
sprintf(line, "%s/%s", user.dir, RCFILE);
if (fp = fopen(line, "r")) {
while (fgets(line, sizeof(line), fp)) parse_command_line(line);
fclose(fp);
}
if (doforward) {
connect_bbs();
wait_for_prompt();
}
if (level == MBOX) {
printf("[THEBOX-1.8-H$]");
if (has_passwd(user.name)) {
if (!doforward) {
l = time(0L);
tm = gmtime(&l);
sprintf(timestamp, "%02d%02d%02d%02d%02d",
tm->tm_mday,
tm->tm_mon + 1,
tm->tm_year % 100,
tm->tm_hour,
tm->tm_min);
get_passwd(user.name, timestamp, boxpassword);
printf(" %s\n", timestamp);
password_ok = 0;
}
else {
printf(" %s\n", boxpassword);
}
} else
{
printf("\n");
*boxpassword = '\0';
}
}
if (doforward) wait_for_prompt();
for (; ; ) {
if (doforward)
strcpy(line, "f>");
else {
if (level == MBOX)
printf(">\n");
else {
*gen_prompt=0;
if((p=strchr(prompt,'\\'))) {
strncat(gen_prompt,prompt,p-prompt);
do {
p++;
if(sl=strchr(p+1,'\\')) {
strncpy(buf,p,sl-p);
buf[sl-p]=0;
} else
strcpy(buf,p);
switch(toupper(*p)) {
case 'D' : l=time((long *) 0);
tm=localtime(&l);
sprintf(buffer,"%02d.%02d.%02d",
tm->tm_mday,
tm->tm_mon,
tm->tm_year % 100);
strcat(gen_prompt,buffer);
strcat(gen_prompt,&buf[1]);
break;
case 'N' : strcat(gen_prompt,"\n");
strcat(gen_prompt,&buf[1]);
break;
case 'W' : strcat(gen_prompt,last_board);
strcat(gen_prompt,&buf[1]);
break;
case 'U' : strcpy(buffer,user.name);
strupc(buffer);
strcat(gen_prompt,buffer);
strcat(gen_prompt,&buf[1]);
break;
case 'H' : strcpy(buffer,myhostname);
strupc(buffer);
strcat(gen_prompt,buffer);
strcat(gen_prompt,&buf[1]);
break;
case 'T' : l=time((long *) 0);
tm=localtime(&l);
sprintf(buffer,"%02d:%02d",tm->tm_hour,tm->tm_min);
strcat(gen_prompt,buffer);
strcat(gen_prompt,&buf[1]);
break;
case '\\': strcat(gen_prompt,"\\");
strcat(gen_prompt,&buf[1]);
p++;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '0': sscanf(buf,"%o",&k);
if(k > 0 && k < 256)
strncat(gen_prompt,(char *) &k, 1);
sl=buf;
while(*sl && (
*sl == '1' ||
*sl == '2' ||
*sl == '3' ||
*sl == '4' ||
*sl == '5' ||
*sl == '6' ||
*sl == '7' ||
*sl == '0')) sl++;
if (*sl) strcat(gen_prompt,sl);
break;
default: strcat(gen_prompt,"\\");
strcat(gen_prompt,buf);
break;
}
while(*p != '\\' && *p) p++;
} while(strchr(p,'\\'));
} else
strcpy(gen_prompt,prompt);
printf("%s",gen_prompt);
}
if (!getstring(line)) exit(1);
}
parse_command_line(line);
doforward = 0;
if (stopped) {
puts("\n*** Interrupt ***");
stopped = 0;
}
}
}
/*---------------------------------------------------------------------------*/
void interrupt_handler(int sig)
{
static struct termio save;
signal(sig, interrupt_handler);
ioctl(0,TCGETA, &save);
save.c_cc[VINTR] = orig_escape;
ioctl(0,TCSETA, &save);
stopped = 1;
}
/*---------------------------------------------------------------------------*/
void alarm_handler(int sig)
{
puts("\n*** Timeout ***");
exit(1);
}
/*---------------------------------------------------------------------------*/
void recv_from_mail_or_news(void)
{
char *cp;
char distr[1024];
char expire[1024];
char line[1024];
int from_priority;
int n;
int state;
struct mail *mail;
while (fgets(line, sizeof(line), stdin)) {
mail = alloc_mail();
*distr = 0;
*expire = 0;
from_priority = 0;
state = 0;
n = strncmp(line, "#! rnews ", 9) ? 0x7fffffff : atoi(line + 9);
for (; ; ) {
switch (state) {
case 0:
if (*line) {
if (from_priority < 1 && !strncmp(line, "From ", 5) && sscanf(line, "From %s", mail->from) == 1)
from_priority = 1;
if (from_priority < 2 && get_header_value("Path:", 1, line, mail->from))
from_priority = 2;
if (from_priority < 3 && get_header_value("From:", 1, line, mail->from))
from_priority = 3;
get_header_value("Newsgroups:", 1, line, mail->to);
get_header_value("Subject:", 0, line, mail->subject);
get_header_value("Message-ID:", 1, line, mail->mid);
get_header_value("Distribution:", 1, line, distr);
get_header_value("Expires:", 1, line, expire);
get_header_value("Bulletin-ID:", 1, line, mail->bid);
} else
state = 1;
break;
case 1:
if (!*line) break;
state = 2;
case 2:
append_line(mail, line);
}
if (n <= 0 || !fgets(line, sizeof(line), stdin)) break;
n -= strlen(line);
strtrim(line);
}
if (*mail->to && from_priority && state == 2) {
if (!strncmp(mail->to, "ampr.bbs.", 9)) strcpy(mail->to, mail->to + 9);
if (cp = strchr(mail->to, ',')) *cp = 0;
if (cp = strrchr(mail->to, '.')) strcpy(mail->to, cp + 1);
if (cp = strchr(distr, ',')) *cp = 0;
if (cp = strrchr(distr, '.')) strcpy(distr, cp + 1);
if (*distr) {
strcat(mail->to, "@");
strcat(mail->to, distr);
}
if (*expire) {
mail->lifetime = parse_date(expire);
if (mail->lifetime != -1) {
mail->lifetime = (mail->lifetime - time((long *) 0)) / DAYS;
if (mail->lifetime < 1) mail->lifetime = 1;
}
}
strcpy(mail->orig_to, mail->to);
route_mail(mail);
}
}
}
/*---------------------------------------------------------------------------*/
int forward_allowed(const struct index *index,const char *name)
{
FILE *fp;
char fname[50];
char line[80];
char cmp[80],cmd[80],tmp[80], junk[1024];
int param;
strcpy(fname,name);
strcat(fname,".NO");
if (fp=fopen(fname,"r"))
{
while (!feof(fp))
{
fgets(line,80,fp);
*cmd = 0; *cmp = 0; *junk = 0;
param=sscanf(line,"%[><@]%s%s",cmd,cmp,junk);
if (param > 1) {
switch(*cmd) {
case '>' : strcpy(tmp,index->to);
break;
case '@' : strcpy(tmp,index->at);
break;
case '<' : strcpy(tmp,index->from);
break;
}
strupc(tmp);strupc(cmp);
if (fnmatch(cmp, tmp, FNM_CASEFOLD) != FNM_NOMATCH) {
fclose(fp);
return 0;
}
}
}
fclose(fp);
}
return 1;
}
/*---------------------------------------------------------------------------*/
int send_allowed(const struct mail *mail, const char *at, const char *name)
{
FILE *fp;
char fname[50];
char line[80];
char cmp[80],cmd[80],tmp[80], junk[1024];
int param;
strcpy(fname,name);
strcat(fname,".NO");
if (fp=fopen(fname,"r"))
{
while (!feof(fp)) {
fgets(line,80,fp);
*cmd = 0; *cmp = 0; *junk = 0;
param=sscanf(line,"%[><@]%s%s",cmd,cmp,junk);
if (param > 1) {
switch(*cmd) {
case '>' : strcpy(tmp,mail->to);
break;
case '@' : strcpy(tmp,at);
break;
case '<' : strcpy(tmp,mail->from);
break;
}
strupc(tmp);strupc(cmp);
if (fnmatch(cmp, tmp, FNM_CASEFOLD) != FNM_NOMATCH) {
fclose(fp);
return 0;
}
}
}
fclose(fp);
}
return 1;
}
/*---------------------------------------------------------------------------*/
void getalias(char *original)
{
char line[1024];
char path[1024];
FILE *fp;
short param;
char alias[80], change[80], junk[1024];
if (fp=fopen(ALIASFILE,"r")) {
if (!callvalid(get_user_from_path(original))){
while(!(feof(fp))){
fgets(line,80,fp);
param=sscanf(line,"%s%s%s",alias, change, junk);
if (*alias != '#' && param > 1) {
strupc(alias);
strupc(change);
strupc(original);
if (fnmatch(alias, original, FNM_CASEFOLD) != FNM_NOMATCH) {
strcpy(original, change);
original[8] = '\0';
fclose(fp);
return ;
}
}
}
}
fclose(fp);
}
else
return ;
}
/*---------------------------------------------------------------------------*/
int read_config()
{
FILE *fp;
static char line[1024];
char cmd[1024];
char buf[1024];
char *s;
int i;
gethostname(myhostname,16);
if (fp = fopen(CONFIGFILE, "r")) {
while (fgets(line, sizeof(line), fp)) {
*cmd=0;
if (sscanf(line,"%s\n",cmd)) {
if (*cmd != '#') {
if (!Strncasecmp(cmd, "cext",4)) {
if (sscanf(line,"%s %s\n",cmd, compressext) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "cprg",4)) {
if (sscanf(line,"%s %s\n",cmd, compress) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "uncom",4)) {
if (sscanf(line,"%s %s\n",cmd, uncompressoption) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "compressopt",9)) {
if (sscanf(line,"%s %s\n",cmd, compressoption) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "bbsadm",6)) {
if (sscanf(line,"%s %s\n",cmd, bbsadm) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "telluser",4)) {
if (sscanf(line,"%s %s\n",cmd, telluser) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "mydomain",6)) {
if (sscanf(line,"%s %s\n",cmd, mydomain) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "myhostname",6)) {
if (sscanf(line,"%s %s\n",cmd, myhostname) < 2) {
halt();
}
strcpy(Myhostname,myhostname);
strupc(Myhostname);
} else
if (!Strncasecmp(cmd, "logging",6)) {
if (sscanf(line,"%s %s\n",cmd, buf) < 2) {
halt();
}
log_reading = (toupper(*buf) == 'Y');
} else
if (!Strncasecmp(cmd, "debug",5)) {
if (sscanf(line,"%s %s\n",cmd, buf) < 2) {
halt();
}
debug = (toupper(*buf) == 'Y');
} else
if (!Strncasecmp(cmd, "fixaddress",5)) {
if (sscanf(line,"%s %s\n",cmd, buf) < 2) {
halt();
}
fix_allowed = !(toupper(*buf) == 'N');
} else
if (!Strncasecmp(cmd, "list",4)) {
if (sscanf(line,"%s %d\n",cmd, &max_list) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "debugfile",6)) {
if (sscanf(line,"%s %s\n",cmd, debugfile) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "helpfile",6)) {
if (sscanf(line,"%s %s\n",cmd, helpfile) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "infofile",6)) {
if (sscanf(line,"%s %s\n",cmd, infofile) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "masterrcfile",6)) {
if (sscanf(line,"%s %s\n",cmd, masterrcfile) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "mailfile",6)) {
if (sscanf(line,"%s %s\n",cmd, mailfile) < 2) {
halt();
}
} else
if (!Strncasecmp(cmd, "station",6)) {
i=sscanf(line,"%s %s\n",cmd, buf);
if (i == 1) {
*station = 0;
} else
{
s=strchr(line, '[');
if (s) {
strcpy(station,s);
station[strlen(station)-1]=0;
} else
{
*station = 0;
}
}
}
}
}
}
fclose(fp);
}
else {
halt();
}
strcpy(Myhostname,myhostname);
strupc(Myhostname);
}
/*---------------------------------------------------------------------------*/
void init_aliasdb(void)
{
const struct cmdtable *cmdp;
struct aliastable *p, *new;
if ((alias_table=malloc(sizeof(struct aliastable))) == NULL) halt();
p=alias_table;
cmdp=cmdtable;
strcpy(alias_table->orig,cmdp->name);
strcpy(alias_table->alias,cmdp->name);
strupc(alias_table->orig);
strupc(alias_table->alias);
alias_table->is_std = 1;
alias_table->level=cmdp->level;
alias_table->next = NULL;
cmdp++;
for(; cmdp->name; cmdp++) {
insert_alias(cmdp->name, cmdp->name, cmdp->level, 1);
}
}
/*---------------------------------------------------------------------------*/
void get_welcomemsg(void)
{
char line[1024];
FILE *fp;
if (fp = fopen(WELCOMEMSG, "r")) {
while (fgets(line,sizeof(line),fp)) printf(line);
fclose(fp);
}
return;
}
/*---------------------------------------------------------------------------*/
void insert_alias(const char *orig, const char *alias,
const int level, char is_std)
{
struct aliastable *p, *ins, *new;
char u_orig[256];
char u_alias[256];
strcpy(u_orig,orig);
strcpy(u_alias,alias);
strupc(u_orig);
strupc(u_alias);
ins=p=alias_table;
while(p && (strcmp(p->orig,u_orig) < 0)) {
ins=p;
p=p->next;
}
if (!strcmp(p->orig,u_orig)) {
strcpy(p->alias,u_alias);
p->is_std=0;
p->level=0;
return;
}
if ((new=malloc(sizeof(struct aliastable))) == NULL) halt();
new->next = p;
strcpy(new->orig,u_orig);
strcpy(new->alias,u_alias);
new->is_std = is_std;
new->level = level;
ins->next = new;
return;
}
/*---------------------------------------------------------------------------*/
void forward_message(const struct index *index, const char *filename,
const char *at, int skip_header)
{
FILE * fp, * dbfp;
char buf[1024];
char buf1[1024];
int c;
int lifetime;
struct tm *tm;
lifetime = ((index->lifetime_h << 8) & 0xff00) + (index->lifetime_l & 0xff) - 1;
if (!forward_allowed(index, user.name))
return;
if (lifetime != -1)
sprintf(buf,"S %s%s%s < %s%s%s # %d",
index->orig_to,
*index->at ? " @ " : "",
at,
index->from,
*index->bid ? " $" : "",
index->bid,
lifetime);
else
sprintf(buf,"S %s%s%s < %s%s%s",
index->orig_to,
*index->at ? " @ " : "",
at,
index->from,
*index->bid ? " $" : "",
index->bid);
if (subject_in_send) {
strcpy(buf1,buf);
if (!strcmp(index->to, "E") || !strcmp(index->to, "M"))
sprintf(buf,"%s %s%s\032",buf1, index->subject,
strcmp(index->to,"M") ? " " : " ");
}
puts(buf);
if (debug) {
if ((fdlock = lock_file(LOCKFILE, 0)) < 0) halt();
dbfp= fopen(debugfile,"a");
fprintf(dbfp,"F> %s: %s\n",user.name, buf);
fclose(dbfp);
close(fdlock);
}
if (!getstring(buf)) exit(1);
if (debug) {
if ((fdlock = lock_file(LOCKFILE, 0)) < 0) halt();
dbfp= fopen(debugfile,"a");
fprintf(dbfp,"%s: %s\n",user.name, buf);
fclose(dbfp);
close(fdlock);
}
switch (*buf) {
case 'O':
case 'o':
if ((!strcmp(index->to, "E") || !strcmp(index->to, "M"))) {
if(!subject_in_send)
puts(*index->subject ? index->subject : "no subject");
wait_for_prompt();
break;
}
else{
puts(*index->subject ? index->subject : "no subject");
fflush(stdout);
tm = gmtime(&index->date);
printf("R:%02d%02d%02d/%02d%02dz @%s.%s %s\n",
tm->tm_year % 100,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
Myhostname,
mydomain,
station);
if (!(fp = fopen (filename, "r"))) halt();
if (skip_header)
while (fgets(buf, sizeof(buf), fp) && *buf != '\n') ;
while ((c = getc(fp)) != EOF) putchar(c);
fclose(fp);
}
puts("\032");
wait_for_prompt();
break;
case 'N':
case 'n':
wait_for_prompt();
break;
case '>':
if ((!strcmp(index->to, "E") || !strcmp(index->to, "M")))
break;
else
exit(1);
default:
exit(1);
}
}
/*---------------------------------------------------------------------------*/
int get_lowest_mesg(int argc, char **argv) {
int i,j;
struct index index;
int lowest=999999;
for (i = 1; i < argc; i++) {
j = atoi(argv[i]);
if (j && (*argv[i-1] != '-')) {
if (j > lowest_on_start) {
if (j < lowest) {
lowest = j;
}
} else
lowest = lowest_on_start;
}
else
if (j && (i > 1 && !atoi(argv[i-2])))
lowest = lowest_on_start;
}
return (lowest);
}
/*---------------------------------------------------------------------------*/
int get_highest_mesg(int argc, char **argv) {
int i,j;
int highest_index, highest=0;
struct index index;
if (lseek(fdindex, -sizeof(index), SEEK_END) < 0) return 0;
if (read(fdindex, &index, sizeof(index)) != sizeof(struct index)) halt();
highest_index = index.mesg+1;
for (i = 1; i < argc; i++) {
j=atoi(argv[i]);
if (j) {
if ((i < argc-1 && *argv[i+1] != '-') || i == argc-1) {
if (j < highest_index) {
if(j > highest) {
highest = j;
}
}
}
else {
if (i < argc-2 && *argv[i+1] == '-' && !atoi(argv[i+2]) ||
i == argc-2 && *argv[i+1] == '-') {
highest = highest_index;
}
}
}
else {
if (*argv[i] == '+' && i < argc - 1 && atoi(argv[i+1])) {
if (highest_index - atoi(argv[i+1]) > highest) {
highest = highest_index - atoi(argv[i+1]);
}
}
}
}
return (highest);
}
/*---------------------------------------------------------------------------*/
mesg_in_command(int argc, char **argv, int mesg, struct index *index)
{
char *to = 0;
int i, ok;
if (!get_index(mesg,index)) return 0;
for(i=1; i < argc; i++)
if(!atoi(argv[i]) && *argv[i] != '-') {
to = argv[i];
strcpy(last_board,to);
strupc(last_board);
}
if (interface_type != wampes && !to)
to = last_board;
for(i=1; i < argc; i++) {
if (to)
if (Strcasecmp(to, index->to)) continue;
if(mesg == atoi(argv[i]))
return 1;
else {
if (*argv[i] == '-' && !is_tell_user) {
ok = 0;
if (atoi(argv[i-1]))
if(mesg > atoi(argv[i-1]))
ok = 1;
else
continue;
if(i < argc-1 && atoi(argv[i+1]))
if(mesg < atoi(argv[i+1]))
ok = 1;
else
continue;
if (ok) return 1;
}
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
int get_highest_on_start(void)
{
int i,j;
struct index index;
if (lseek(fdindex, -sizeof(index), SEEK_END) < 0) return 0;
if (read(fdindex, &index, sizeof(index)) != sizeof(struct index)) halt();
return (index.mesg);
}
/*---------------------------------------------------------------------------*/
int get_lowest_on_start(void)
{
int i = 0;
struct index index;
while(get_index(i, &index) && (index.flags & DELETED)) i++;
return (index.mesg);
}
/*---------------------------------------------------------------------------*/
void check_cmdaliases(char *line)
{
char buffer[2048];
char cmd[256];
char *f;
char *t;
struct aliastable *p;
f=line;
while(isspace(uchar(*f))) f++;
t=f;
while(isalpha(uchar(*t))) t++;
if (t==f) return;
strncpy(cmd,f,t-f); cmd[t-f]=0;
strupc(cmd);
p=alias_table;
while (p) {
if(!strncmp(cmd,p->orig,strlen(cmd)) && level >= p->level) {
strcpy(buffer, p->alias);
strcat(buffer,t);
strcpy(line,buffer);
if (!strncmp(cmd, p->alias,strlen(cmd))) return;
check_cmdaliases(line);
return;
}
p=p->next;
}
return;
}
/*---------------------------------------------------------------------------*/
void connect_bbs(void)
{
char *address;
int addrlen;
int fd;
struct sockaddr *addr;
if (!(address = connect_addr(user.name))) exit(1);
if (!(addr = build_sockaddr("unix:/tcp/.sockets/netcmd", &addrlen))) exit(1);
if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) exit(1);
if (connect(fd, addr, addrlen)) exit(1);
if (fd != 0) dup2(fd, 0);
if (fd != 1) dup2(fd, 1);
if (fd != 2) dup2(fd, 2);
if (fd > 2) close(fd);
fdopen(0, "r+");
fdopen(1, "r+");
fdopen(2, "r+");
printf("connect %s\n", address);
}
/*---------------------------------------------------------------------------*/
void parse_command_line(char *line)
{
#define STARTDELIM "#$<["
#define ANYDELIM "@>]"
#define UANYDELIM "=-+;"
char *argv[256];
char *f;
char *t;
char buf[2048];
char delim[32];
int argc;
int len;
int quote;
const struct cmdtable *cmdp;
FILE *dbfp;
if (debug && (*line != '[')) {
if ((fdlock = lock_file(LOCKFILE, 0)) < 0) halt();
dbfp= fopen(debugfile,"a");
fprintf(dbfp,"%s: %s\n",user.name, line);
fclose(dbfp);
close(fdlock);
}
if (!password_ok && (*line != '[')) return;
if (level != MBOX) check_cmdaliases(line);
strcpy(delim,ANYDELIM);
if (level != MBOX) strcat(delim,UANYDELIM);
f = line;
do {
argc = 0;
memset((char *) argv, 0, sizeof(argv));
for (t = buf; ; ) {
while (isspace(uchar(*f))) f++;
if (!*f) break;
if (level != MBOX && *f == ';') {
f++;
break;
}
argv[argc++] = t;
if (*f == '"' || *f == '\'') {
quote = *f++;
while (*f && *f != quote) *t++ = *f++;
if (*f) f++;
} else if (strchr(STARTDELIM,*f) || strchr(delim, *f)) {
*t++ = *f++;
} else {
while (*f && !isspace(uchar(*f)) && !strchr(delim, *f)) *t++ = *f++;
}
*t++ = 0;
}
if (!argc) return;
if (!(len = strlen(*argv))) return;
for (cmdp = cmdtable; ; cmdp++)
if (!cmdp->name ||
level >= cmdp->level && !Strncasecmp(cmdp->name, *argv, len)) {
if (argc >= cmdp->argc) {
(*cmdp->fnc)(argc, argv);
if (level != MBOX) printf("\n");
}
else {
errors++;
if (level == MBOX)
puts("NO");
else
printf("The %s command requires more arguments. Type ? %s for help.\n",
cmdp->name, cmdp->name);
}
break;
}
} while(f);
if (level == MBOX && errors >= 3) exit(1);
}
/*---------------------------------------------------------------------------*/
char *connect_addr(char *host)
{
FILE *fp;
char *addr;
static char line[1024];
static char buf[80];
char cmd[32];
char *h, *p;
int i;
addr = 0;
if (fp = fopen(CONFIGFILE, "r")) {
while (fgets(line, sizeof(line), fp)) {
*cmd=0;
if (sscanf(line,"%s\n",cmd)) {
if (*cmd != '#') {
strlwc(cmd);
if (!strncmp(cmd, "mbox",4)) {
for (p = line+strlen(cmd); isspace(uchar(*p)); p++) ;
for (h = p; *p && !isspace(uchar(*p)); p++) ;
if (*p) *p++ = 0;
if (!strcmp(h, host)) {
addr = strtrim(p);
break;
}
}
}
}
}
fclose(fp);
}
return addr;
}
int Atoi(char *str)
{
int i;
for(i=0;i < strlen(str); i++)
if (!isdigit(str[i])) return 0;
return (atoi(str));
}
#ifdef TAYLOR103
int forward_mail()
{
struct filelist {
struct filelist *next;
char name[16];
};
DIR *dirp;
FILE * fp;
char bid[1024];
char cfile[1024];
char dfile[1024];
char dirname[1024];
char from[1024];
char line[1024];
char subject[1024];
char tmp1[1024];
char tmp2[1024];
char to[1024];
char xfile[1024];
struct dirent *dp;
struct filelist *filelist = 0;
struct filelist *p;
struct filelist *q;
struct index index;
struct stat statbuf;
int count;
sprintf(dirname, "/usr/spool/uucp/%s", user.name);
if (dirp = opendir(dirname)) {
for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
if (*dp->d_name != 'C') continue;
p = malloc(sizeof(*p));
strcpy(p->name, dp->d_name);
if (!filelist || strcmp(p->name, filelist->name) < 0) {
p->next = filelist;
filelist = p;
} else {
for (q = filelist; q->next && strcmp(p->name, q->next->name) > 0; q = q->next) ;
p->next = q->next;
q->next = p;
}
}
closedir(dirp);
for (; p = filelist; filelist = p->next, free(p)) {
sprintf(cfile, "/usr/spool/uucp/%s/%s", user.name, p->name);
if (!(fp = fopen(cfile, "r"))) continue;
*dfile = *xfile = 0;
while (fgets(line, sizeof(line), fp)) {
if (*line == 'S' && sscanf(line, "%*s %*s %s %*s %*s %s", tmp1, tmp2) == 2 && *tmp1 == 'D')
sprintf(dfile, "/usr/spool/uucp/%s/%s", user.name, tmp2);
if (*line == 'S' && sscanf(line, "%*s %*s %s %*s %*s %s", tmp1, tmp2) == 2 && *tmp1 == 'X')
sprintf(xfile, "/usr/spool/uucp/%s/%s", user.name, tmp2);
}
fclose(fp);
if (!*dfile || !*xfile) continue;
if (!(fp = fopen(xfile, "r"))) continue;
*to = 0;
while (fgets(line, sizeof(line), fp))
if (!strncmp(line, "C rmail ", 8)) {
sprintf(to, "%s!%s", user.name, line + 8);
strtrim(to);
break;
}
fclose(fp);
if (!*to) continue;
if (!(fp = fopen(dfile, "r"))) continue;
*from = *subject = *bid = 0;
if (fscanf(fp, "From %s", tmp1) == 1) {
if (!strcmp(tmp1, "MAILER-DAEMON") || !strcmp(tmp1, "!"))
strcpy(tmp1, myhostname);
sprintf(from, "%s!%s", myhostname, tmp1);
strtrim(from);
while (fgets(line, sizeof(line), fp)) {
if (*line == '\n') break;
get_header_value("Subject:", 0, line, subject);
get_header_value("Bulletin-ID:", 1, line, bid);
}
}
fclose(fp);
if (!*from) continue;
if (stat(cfile, &statbuf)) continue;
memset((char *) &index, 0, sizeof(index));
index.date = statbuf.st_mtime;
strncpy(index.bid, bid, LEN_BID);
index.bid[LEN_BID] = 0;
strupc(index.bid);
strncpy(index.subject, subject, LEN_SUBJECT);
index.subject[LEN_SUBJECT] = 0;
strncpy(index.to, get_user_from_path(to), LEN_TO);
index.to[LEN_TO] = 0;
strupc(index.to);
strcpy(index.orig_to,index.to);
strncpy(index.at, get_host_from_path(to), LEN_AT);
index.at[LEN_AT] = 0;
strupc(index.at);
strcpy(_at, get_host_from_path(to));
strupc(_at);
strncpy(index.from, get_user_from_path(from), LEN_FROM);
index.from[LEN_FROM] = 0;
strupc(index.from);
forward_message(&index, dfile, 1);
if (unlink(cfile)) halt();
if (unlink(dfile)) halt();
if (unlink(xfile)) halt();
}
}
return 0;
}
#endif
#ifdef TAYLOR104
int forward_mail()
{
struct filelist {
struct filelist *next;
char name[16];
};
DIR *dirp;
FILE * fp;
char bid[1024];
char cfile[1024];
char dfile[1024];
char dirname[1024];
char from[1024];
char line[1024];
char subject[1024];
char tmp1[1024];
char tmp2[1024];
char tmp3[1024];
char to[1024];
char xfile[1024];
struct dirent *dp;
struct filelist *filelist = 0;
struct filelist *p;
struct filelist *q;
struct index index;
struct stat statbuf;
sprintf(dirname, "/usr/spool/uucp/%s", user.name);
if (dirp = opendir(dirname)) {
for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
if (*dp->d_name != 'C') continue;
p = malloc(sizeof(*p));
strcpy(p->name, dp->d_name);
if (!filelist || strcmp(p->name, filelist->name) < 0) {
p->next = filelist;
filelist = p;
} else {
for (q = filelist; q->next && strcmp(p->name, q->next->name) > 0; q = q->next) ;
p->next = q->next;
q->next = p;
}
}
closedir(dirp);
for (; p = filelist; filelist = p->next, free(p)) {
sprintf(cfile, "/usr/spool/uucp/%s/%s", user.name, p->name);
if (!(fp = fopen(cfile, "r"))) continue;
*dfile = *xfile = *to = 0;
while (fgets(line, sizeof(line), fp)) {
if (*line == 'E' && sscanf(line, "%*s %*s %*s %*s %*s %s %*s %*s %*s %s %s", tmp1, tmp2, tmp3) == 3 && *tmp1 == 'D' && !strcmp(tmp2, "rmail")) {
sprintf(dfile, "/usr/spool/uucp/%s/%s", user.name, tmp1);
sprintf(to, "%s!%s", user.name, tmp3);
strtrim(to);
}
if (*line == 'S' && sscanf(line, "%*s %*s %s %*s %*s %s", tmp1, tmp2) == 2 && *tmp1 == 'D')
sprintf(dfile, "/usr/spool/uucp/%s/%s", user.name, tmp2);
if (*line == 'S' && sscanf(line, "%*s %*s %s %*s %*s %s", tmp1, tmp2) == 2 && *tmp1 == 'X')
sprintf(xfile, "/usr/spool/uucp/%s/%s", user.name, tmp2);
}
fclose(fp);
if (!*dfile) continue;
if (*xfile) {
if (!(fp = fopen(xfile, "r"))) continue;
while (fgets(line, sizeof(line), fp))
if (!strncmp(line, "C rmail ", 8)) {
sprintf(to, "%s!%s", user.name, line + 8);
strtrim(to);
break;
}
fclose(fp);
}
if (!*to) continue;
if (!(fp = fopen(dfile, "r"))) continue;
*from = *subject = *bid = 0;
if (fscanf(fp, "From %s", tmp1) == 1) {
if (!strcmp(tmp1, "MAILER-DAEMON") || !strcmp(tmp1, "!"))
strcpy(tmp1, myhostname);
sprintf(from, "%s!%s", myhostname, tmp1);
strtrim(from);
while (fgets(line, sizeof(line), fp)) {
if (*line == '\n') break;
get_header_value("Subject:", 0, line, subject);
get_header_value("Bulletin-ID:", 1, line, bid);
}
}
fclose(fp);
if (!*from) continue;
if (stat(cfile, &statbuf)) continue;
memset((char *) &index, 0, sizeof(index));
index.date = statbuf.st_mtime;
strncpy(index.bid, bid, LEN_BID);
index.bid[LEN_BID] = 0;
strupc(index.bid);
strncpy(index.subject, subject, LEN_SUBJECT);
index.subject[LEN_SUBJECT] = 0;
strncpy(index.to, get_user_from_path(to), LEN_TO);
index.to[LEN_TO] = 0;
strupc(index.to);
strcpy(index.orig_to,index.to);
strncpy(index.at, get_host_from_path(to), LEN_AT);
index.at[LEN_AT] = 0;
strupc(index.at);
strncpy(index.from, get_user_from_path(from), LEN_FROM);
index.from[LEN_FROM] = 0;
strupc(index.from);
forward_message(&index, dfile, strupc(get_host_from_path(to)), 1);
if (unlink(cfile)) halt();
if (unlink(dfile)) halt();
if (*xfile && unlink(xfile)) halt();
}
}
return 0;
}
#endif
/*---------------------------------------------------------------------------*/
int isvaliduser(char *s) {
FILE *fp;
char line[1024], buffer[1024];
if (fp = fopen(mailfile, "r")) {
while (fgets(line, sizeof(line), fp)) {
*buffer=0;
if (sscanf(line,"%s\n",buffer)) {
if (*buffer != '#') {
if(!strcmp(s, buffer)) {
fclose(fp);
return 1;
}
}
}
}
}
fclose(fp);
return 0;
}
/*---------------------------------------------------------------------------*/
int has_passwd(char *call)
{
FILE *fp;
char filename[80];
strcpy(filename,call);
strcat(filename,".pwd");
strlwc(filename);
if ((fp=fopen(filename,"r")) == NULL)
return(0);
fclose(fp);
return(1);
}
/*---------------------------------------------------------------------------*/
int get_passwd(char *call, char *timestamp, char *password)
{
int fd;
char filename[80];
int offset;
int min, hour, day;
char buf[1024];
int i;
strcpy(filename,call);
strcat(filename,".pwd");
strlwc(filename);
if ((fd=open(filename,O_RDONLY)) == -1)
return(0);
if (strlen(timestamp) != 10) return 0;
strncpy(buf, timestamp, 2); buf[2] = '\0';
day = atoi(buf);
strncpy(buf, ×tamp[6], 2); buf[2] = '\0';
hour = atoi(buf);
strncpy(buf, ×tamp[8], 2); buf[2] = '\0';
min = atoi(buf);
offset = ((min + day) % 60) * 27 + hour;
if (hour > 23) halt();
if(lseek(fd, (long) (offset), SEEK_SET) == -1) halt();
if(read(fd, password, 4) < 1) halt();
password[4] = '\0';
close(fd);
return 1;
}
/*---------------------------------------------------------------------------*/